package cn.etynit.test;

import cn.etynit.utils.ESClientUtil;
import com.sun.org.apache.xpath.internal.operations.Lte;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.search.MatchQuery;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;

import java.util.HashMap;

public class EsTestTwo {
    /**
     * 使用循环的方式新增
     */
    @Test
    public void test() throws Exception{
        // 获取客户端链接
        TransportClient client = ESClientUtil.getClient();
        for (int i = 0; i < 100; i++) {
            // 指定要操作的索引库，类型
            IndexRequestBuilder indexRequestBuilder = client.prepareIndex("myhome", "emp");
            indexRequestBuilder.setId(i+"");
            HashMap<String, Object> map = new HashMap<>();
            map.put("id",i);
            if (i % 3 == 0){
                map.put("name","你看得见我吗？");
            }else if (i % 3 == 1){
                map.put("name","我看到你了！");
            }else {
                map.put("name","我在等你！");
            }
            map.put("age",i);
            map.put("sex",1 % 2 == 1);
            // 放入新增数据，同时获取执行结果
            IndexResponse indexResponse = indexRequestBuilder.setSource(map).get();
            System.out.println(indexResponse);
        }
    }

    /**
     * 通过id获取数据
     * @throws Exception
     */
    @Test
    public void testGet() throws Exception{
        // 获取客户端链接
        TransportClient client = ESClientUtil.getClient();
        // 指定要操作的索引库，类型和id
        GetRequestBuilder getRequestBuilder = client.prepareGet("myhome", "emp", "1");
        GetResponse documentFields = getRequestBuilder.get();
        System.out.println(documentFields);
    }

    /**
     * 根据id修改
     * @throws Exception
     */
    @Test
    public void testUpdate() throws Exception{
        // 获取客户端链接
        TransportClient client = ESClientUtil.getClient();
        // 指定要操作的索引库，类型和id
        UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate("myhome", "emp", "1");
        // new一个map来装修改的值
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", "你像忘了礼拜几的宇航员");
        UpdateResponse updateResponse = updateRequestBuilder.setDoc(map).get();
        System.out.println(updateResponse);
    }

    /**
     * 根据id来删除
     * @throws Exception
     */
    @Test
    public void testDel() throws Exception{
        // 获取客户端链接
        TransportClient client = ESClientUtil.getClient();
        // 指定要操作的索引库，类型和id
        DeleteRequestBuilder deleteRequestBuilder = client.prepareDelete("myhome", "emp", "100");
        System.out.println(deleteRequestBuilder);
    }

    /**
     * - 查询employee表
     * - name包含：我在源码   must->match
     * - age在1~12之间  filter->range
     * - sex=1 filter
     * - 每页大小2 size=10
     * - 从3页开始查 from= 0~9 10~19 20 ~29
     * - 按照age倒序 sort=desc
     */
    @Test
    public void testComplex() throws Exception{
        // 获取客户端链接
        TransportClient client = ESClientUtil.getClient();
        // 指定要操作的索引库，类型
        SearchRequestBuilder myhome = client.prepareSearch("myhome").setTypes("emp");
        // 设置搜索条件  当一个方法需要传递的对象是一个接口的时候，那么我们可以如何传递：
        /**
         * 1.匿名内部类
         * 2.搞个实现类
         * 3.传递给我们准备好的实现类
         * 4.接口里面有没有方法可以创建自己
         * 5.有没有此接口的相关工具类，命名规则：
         *  1.接口类名打头+Util
         *  2.接口类名打头+Utils
         *  3.接口类名打头+Holder
         *  4.接口类名打头+s
         */
        // 首先使用QueryBuilders中的方法执行boolQuery，有多个条件的查询：query（查询），bool（多个组合条件）
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // bool下面执行的是mast，DSL查询，相当与and,mast它里面是match（分词后进行匹配） // "name"用matchQuery分词后进行匹配查询
        // filter跟must是平级的，filter是DSL过滤,相当于=
        // sex用termQuery是全套匹配，不会分词
        // age使用rangeQuery 匹配某个范围，这个里匹配从1到12
        boolQuery.must(QueryBuilders.matchQuery("name","我看"))
                .filter(QueryBuilders.termQuery("sex",true))
                .filter(QueryBuilders.rangeQuery("age").gte(1).lte(20));
        // 添加查询条件
        myhome.setQuery(boolQuery);
        // size每页展示条数（跟query平级）
        myhome.setSize(10);
        // From从哪一条数据开始取，以数值的下一条开始取
        myhome.setFrom(0);
        // addSort，SortOrder.DESC以age来进行倒序排列,ASC升序
        myhome.addSort("age", SortOrder.ASC);
        SearchResponse searchResponse = myhome.get();
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }
    }

}
